﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using MvcEngine.Mvc.Models.ViewModels;
using MvcEngine.Core.Utils;
using MvcEngine.Core;

using MvcEngine.Core.Repositories;
using MvcEngine.Core.Helpers;
using MvcEngine.Mvc.Extensions;
using MvcEngine.Core.Validation;
using System.Text.RegularExpressions;
using MvcEngine.Mvc.Models;
using MvcEngine.Core.Exceptions;
using MvcEngine.Core.Services;
using MvcEngine.Core.Localization;
using MvcEngine.Mvc.Filters;
using MvcEngine.Core.Account;
using MvcEngine.Mvc.Controllers;
using MvcEngine.Core.Content;
using AutoMapper;

namespace MvcEngine.Mvc.StarterSite.Controllers
{
    public class AccountController : BaseController
    {
        #region Private Fields

        private IUserRepository userRepository = null;

        #endregion

        #region Constructors

        public AccountController(IUserRepository userRepository)
        {
            this.userRepository = userRepository;
        }

        #endregion


        #region Account

        [AcceptVerbs(HttpVerbs.Get)]
        public MvcEngineModel Register()
        {
            return new AccountViewModel();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ActionName("Register")]
        public virtual object RegisterAccount(AccountViewModel model)
        {
            if (ModelState.IsValid)
            {
                User user = IoC.Resolve<User>();
                user = Mapper.Map<AccountViewModel, User>(model, user);
                user.Id = Guid.NewGuid();
                AccountManager.Current.SaveUser(user);
                //EmailHelper.Current.SendNotificationMessage(user, Url.AbsolutePath(Url.ActivateAccount(user.CreateGuid.ToString())));
                return RegisterSuccess();
            }
            return Register();
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public MvcEngineModel RegisterSuccess()
        {
            return new MvcEngineModel() { ViewName = "RegisterSuccess" };
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public virtual object ActivateAccount(string key)
        {
            if (!GuidValidator.IsValidGuid(key))
            {
                return new MvcEngineModel() { ViewName = "IncorrectKey" };
            }

            Guid id = new Guid(key);
            User user = userRepository.GetUserByCreateKey(id);
            if (user == null)
            {
                return new MvcEngineModel() { ViewName = "WrongKey" };
            }

            user.IsApproved = true;
            user.CreateGuid = null;

            AccountManager.Current.SaveUser(user);
            FormsAuthenticationHelper.Current.SignIn(user.Email, false);
            return new MvcEngineModel();
        }


        [AcceptVerbs(HttpVerbs.Get)]
        public MvcEngineModel ForgotPassword()
        {
            return new ForgotPasswordViewModel() { ViewName = "ForgotPassword" };
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ActionName("ForgotPassword")]
        public virtual object AccountForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                User user = AccountManager.Current.GetUser(model.Email);
                user.RestoreGuid = Guid.NewGuid();
                AccountManager.Current.SaveUser(user);
                //EmailHelper.Current.SendRestorePasswordLink(user, Url.AbsolutePath(Url.ChangePassword(user.RestoreGuid.ToString())));
                return new MvcEngineModel() { ViewName = "ForgotPasswordStatus" };
            }
            return ForgotPassword();
        }


        [AcceptVerbs(HttpVerbs.Get)]
        public virtual object ChangePassword(string key)
        {
            if (!GuidValidator.IsValidGuid(key))
                return new MvcEngineModel() { ViewName = "IncorrectKey" };
            Guid restoreUserGuid = new Guid(key);
            User user = userRepository.GetUserByRestoreKey(restoreUserGuid);
            if (user == null)
                return new MvcEngineModel() { ViewName = "WrongKey" };

            return new ChangePasswordViewModel() { Key = key, ViewName = "ChangePassword" };
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ActionName("ChangePassword")]
        public virtual object ChangeUserPassword(ChangePasswordViewModel model, string key)
        {
            if (ModelState.IsValid)
            {
                if (!GuidValidator.IsValidGuid(key))
                    return new MvcEngineModel() { ViewName = "IncorrectKey" };
                Guid restoreUserGuid = new Guid(key);
                User user = userRepository.GetUserByRestoreKey(restoreUserGuid);
                if (user == null)
                    return new MvcEngineModel() { ViewName = "WrongKey" };


                user.Password = model.Password;
                user.RestoreGuid = null;
                user.PasswordSalt = HashHelper.Current.GenerateHashString();
                user.Password = HashHelper.Current.ComputeHash(user.Password, user.PasswordSalt);
                user.ModifiedDate = DateTime.Now;

                AccountManager.Current.SaveUser(user);
                FormsAuthenticationHelper.Current.SignIn(user.Email, false);
                return new MvcEngineModel() { ViewName = "ChangePasswordStatus" };
            }
            return ChangePassword(key);
        }

        #endregion

        #region Login
        [AcceptVerbs(HttpVerbs.Get)]
        public virtual MvcEngineModel LogOnControl()
        {
            Guid accountPage = Guid.Empty;
            if (SiteContext.Current.Site.AccountPage.HasValue)
                accountPage = SiteContext.Current.Site.AccountPage.Value;
            else
                accountPage = SiteContext.Current.Site.DefaultPage;

            return new LoginViewModel() { AccountPage = ContentManager.Current.GetPage(accountPage).Name };
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [AntiForgeryValidationFilter]
        public virtual object LogOnControl(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                FormsAuthenticationHelper.Current.SignIn(model.Email, model.RememberMe);
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return Redirect(Url.Page(SiteContext.Current.Site.DefaultPage));
                }
            }
            return LogOnControl();
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public virtual ActionResult LogOutControl()
        {
            FormsAuthenticationHelper.Current.SignOut();
            return Redirect(Url.Page(SiteContext.Current.CurrentPage.Id));
        }

        #endregion


        #region ChangeLanguage
        
        public void Language(string language)
        {
            if (string.IsNullOrEmpty(language))
            {
                LogHelper.Current.WriteError("Language can't be null or empty.");
                Response.Redirect(Request.UrlReferrer.ToString());

            }

            CultureInfo culture = null;
            try
            {
                culture = new CultureInfo(language);
            }
            catch (ArgumentException)
            {
                culture = new CultureInfo(SiteContext.Current.Site.Culture);
            }

            Response.Cookies.Add(new HttpCookie(Constants.UserSettings.SelectedCulture, language));
            Response.Redirect(Request.UrlReferrer.ToString());
        } 

        #endregion

    }
}
